package com.flower.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.flower.domain.entity.*;
import com.flower.domain.vo.admin.analysis.*;
import com.flower.mapper.*;
import com.flower.service.DataAnalysisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 数据分析服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DataAnalysisServiceImpl implements DataAnalysisService {

    private final OrderMapper orderMapper;
    private final OrderItemMapper orderItemMapper;
    private final ProductMapper productMapper;
    private final ShopMapper shopMapper;
    private final CategoryMapper categoryMapper;
    private final AddressMapper addressMapper;
    private final FlowerEncyclopediaMapper flowerEncyclopediaMapper;

    /**
     * 获取销售概览数据
     */
    @Override
    public SalesOverviewVO getSalesOverview() {
        LocalDate today = LocalDate.now();
        LocalDate yesterday = today.minusDays(1);
        
        // 今日数据
        Integer todaySales = getTotalSalesForDateRange(
                today.atStartOfDay(), 
                today.atTime(LocalTime.MAX));
        Integer todayOrders = getOrderCountForDateRange(
                today.atStartOfDay(), 
                today.atTime(LocalTime.MAX));
        
        // 昨日数据
        Integer yesterdaySales = getTotalSalesForDateRange(
                yesterday.atStartOfDay(), 
                yesterday.atTime(LocalTime.MAX));
        Integer yesterdayOrders = getOrderCountForDateRange(
                yesterday.atStartOfDay(), 
                yesterday.atTime(LocalTime.MAX));
        
        // 本周数据
        LocalDate startOfWeek = today.with(DayOfWeek.MONDAY);
        Integer weekSales = getTotalSalesForDateRange(
                startOfWeek.atStartOfDay(), 
                today.atTime(LocalTime.MAX));
        Integer weekOrders = getOrderCountForDateRange(
                startOfWeek.atStartOfDay(), 
                today.atTime(LocalTime.MAX));
        
        // 上周同期数据
        LocalDate lastWeekStart = startOfWeek.minusWeeks(1);
        LocalDate lastWeekEnd = today.minusWeeks(1);
        Integer lastWeekSales = getTotalSalesForDateRange(
                lastWeekStart.atStartOfDay(), 
                lastWeekEnd.atTime(LocalTime.MAX));
        
        // 本月数据
        LocalDate startOfMonth = today.withDayOfMonth(1);
        Integer monthSales = getTotalSalesForDateRange(
                startOfMonth.atStartOfDay(), 
                today.atTime(LocalTime.MAX));
        Integer monthOrders = getOrderCountForDateRange(
                startOfMonth.atStartOfDay(), 
                today.atTime(LocalTime.MAX));
        
        // 上月同期数据
        LocalDate lastMonthStart = today.minusMonths(1).withDayOfMonth(1);
        LocalDate lastMonthEnd = today.minusMonths(1).withDayOfMonth(
                today.getDayOfMonth() > today.minusMonths(1).lengthOfMonth() ? 
                today.minusMonths(1).lengthOfMonth() : today.getDayOfMonth());
        Integer lastMonthSales = getTotalSalesForDateRange(
                lastMonthStart.atStartOfDay(), 
                lastMonthEnd.atTime(LocalTime.MAX));
        
        // 计算环比增长率
        Double todaySalesGrowth = calculateGrowthRate(todaySales, yesterdaySales);
        Double weekSalesGrowth = calculateGrowthRate(weekSales, lastWeekSales);
        Double monthSalesGrowth = calculateGrowthRate(monthSales, lastMonthSales);
        
        return new SalesOverviewVO(
                todaySales, yesterdaySales, weekSales, monthSales,
                todayOrders, yesterdayOrders, weekOrders, monthOrders,
                todaySalesGrowth, weekSalesGrowth, monthSalesGrowth
        );
    }

    /**
     * 获取销售趋势数据
     */
    @Override
    public SalesTrendVO getSalesTrend(LocalDate startDate, LocalDate endDate, String timeUnit) {
        // 设置默认日期范围
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }
        
        List<String> timeLabels = new ArrayList<>();
        List<Integer> salesData = new ArrayList<>();
        List<Integer> orderData = new ArrayList<>();
        
        switch (timeUnit) {
            case "day":
                // 按天统计
                long daysBetween = ChronoUnit.DAYS.between(startDate, endDate) + 1;
                DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("MM-dd");
                
                for (int i = 0; i < daysBetween; i++) {
                    LocalDate date = startDate.plusDays(i);
                    timeLabels.add(date.format(dayFormatter));
                    
                    LocalDateTime dayStart = date.atStartOfDay();
                    LocalDateTime dayEnd = date.atTime(LocalTime.MAX);
                    
                    salesData.add(getTotalSalesForDateRange(dayStart, dayEnd));
                    orderData.add(getOrderCountForDateRange(dayStart, dayEnd));
                }
                break;
                
            case "week":
                // 按周统计
                LocalDate currentWeekStart = startDate.with(DayOfWeek.MONDAY);
                LocalDate endWeekStart = endDate.with(DayOfWeek.MONDAY);
                
                while (!currentWeekStart.isAfter(endWeekStart)) {
                    LocalDate weekEnd = currentWeekStart.plusDays(6);
                    if (weekEnd.isAfter(endDate)) {
                        weekEnd = endDate;
                    }
                    
                    String weekLabel = currentWeekStart.format(DateTimeFormatter.ofPattern("MM-dd")) 
                            + "~" + weekEnd.format(DateTimeFormatter.ofPattern("MM-dd"));
                    timeLabels.add(weekLabel);
                    
                    LocalDateTime weekStart = currentWeekStart.atStartOfDay();
                    LocalDateTime weekEndTime = weekEnd.atTime(LocalTime.MAX);
                    
                    salesData.add(getTotalSalesForDateRange(weekStart, weekEndTime));
                    orderData.add(getOrderCountForDateRange(weekStart, weekEndTime));
                    
                    currentWeekStart = currentWeekStart.plusWeeks(1);
                }
                break;
                
            case "month":
                // 按月统计
                LocalDate currentMonthStart = startDate.withDayOfMonth(1);
                LocalDate endMonthStart = endDate.withDayOfMonth(1);
                
                while (!currentMonthStart.isAfter(endMonthStart)) {
                    LocalDate monthEnd = currentMonthStart.with(TemporalAdjusters.lastDayOfMonth());
                    if (monthEnd.isAfter(endDate)) {
                        monthEnd = endDate;
                    }
                    
                    timeLabels.add(currentMonthStart.format(DateTimeFormatter.ofPattern("yyyy-MM")));
                    
                    LocalDateTime monthStart = currentMonthStart.atStartOfDay();
                    LocalDateTime monthEndTime = monthEnd.atTime(LocalTime.MAX);
                    
                    salesData.add(getTotalSalesForDateRange(monthStart, monthEndTime));
                    orderData.add(getOrderCountForDateRange(monthStart, monthEndTime));
                    
                    currentMonthStart = currentMonthStart.plusMonths(1);
                }
                break;
                
            default:
                // 默认按天统计
                return getSalesTrend(startDate, endDate, "day");
        }
        
        return new SalesTrendVO(timeLabels, salesData, orderData);
    }

    /**
     * 获取订单状态分布
     */
    @Override
    public OrderStatusDistributionVO getOrderStatusDistribution() {
        List<String> statusNames = Arrays.asList("待付款", "待发货", "待收货", "已完成", "已取消");
        List<Integer> counts = new ArrayList<>();
        
        // 查询各状态订单数量
        for (int i = 0; i < 5; i++) {
            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getStatus, i);
            int count = orderMapper.selectCount(queryWrapper).intValue();
            counts.add(count);
        }
        
        return new OrderStatusDistributionVO(statusNames, counts);
    }

    /**
     * 获取热销商品排行
     */
    @Override
    public TopProductsVO getTopProducts(Integer limit) {
        // 查询已完成订单的订单项
        LambdaQueryWrapper<Order> orderQueryWrapper = new LambdaQueryWrapper<>();
        orderQueryWrapper.eq(Order::getStatus, 3); // 已完成状态
        List<Order> completedOrders = orderMapper.selectList(orderQueryWrapper);
        
        if (completedOrders.isEmpty()) {
            return new TopProductsVO(Collections.emptyList());
        }
        
        List<Integer> orderIds = completedOrders.stream()
                .map(Order::getOrderId)
                .collect(Collectors.toList());
        
        // 查询这些订单的订单项
        LambdaQueryWrapper<OrderItem> itemQueryWrapper = new LambdaQueryWrapper<>();
        itemQueryWrapper.in(OrderItem::getOrderId, orderIds);
        List<OrderItem> orderItems = orderItemMapper.selectList(itemQueryWrapper);
        
        // 按商品ID分组统计
        Map<Integer, Integer> productQuantityMap = new HashMap<>();
        Map<Integer, Integer> productAmountMap = new HashMap<>();
        
        for (OrderItem item : orderItems) {
            Integer productId = item.getProductId();
            Integer quantity = item.getQuantity();
            Integer subtotal = item.getSubtotal();
            
            productQuantityMap.put(productId, productQuantityMap.getOrDefault(productId, 0) + quantity);
            productAmountMap.put(productId, productAmountMap.getOrDefault(productId, 0) + subtotal);
        }
        
        // 获取商品详情并排序
        List<TopProductsVO.ProductSalesVO> productSalesList = new ArrayList<>();
        
        for (Map.Entry<Integer, Integer> entry : productQuantityMap.entrySet()) {
            Integer productId = entry.getKey();
            Integer quantity = entry.getValue();
            Integer amount = productAmountMap.get(productId);
            
            Product product = productMapper.selectById(productId);
            Shop shop = shopMapper.selectById(product.getShopId());
            TopProductsVO.ProductSalesVO productSales = new TopProductsVO.ProductSalesVO(
                    productId,
                    product.getShopId(),
                    product.getProductName(),
                    shop.getShopName(),
                    product.getImage(),
                    quantity,
                    amount
            );
            productSalesList.add(productSales);
        }
        
        // 按销售额排序并限制数量
        productSalesList.sort((a, b) -> b.getAmount().compareTo(a.getAmount()));
        if (productSalesList.size() > limit) {
            productSalesList = productSalesList.subList(0, limit);
        }
        
        return new TopProductsVO(productSalesList);
    }

    /**
     * 获取店铺销售排行
     */
    @Override
    public TopShopsVO getTopShops(Integer limit) {
        // 查询已完成订单
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getStatus, 3); // 已完成状态
        List<Order> completedOrders = orderMapper.selectList(queryWrapper);
        
        if (completedOrders.isEmpty()) {
            return new TopShopsVO(Collections.emptyList());
        }
        
        // 按店铺分组统计
        Map<Integer, Integer> shopOrderCountMap = new HashMap<>();
        Map<Integer, Integer> shopSalesAmountMap = new HashMap<>();
        
        for (Order order : completedOrders) {
            Integer shopId = order.getShopId();
            Integer amount = order.getTotalAmount();
            
            shopOrderCountMap.put(shopId, shopOrderCountMap.getOrDefault(shopId, 0) + 1);
            shopSalesAmountMap.put(shopId, shopSalesAmountMap.getOrDefault(shopId, 0) + amount);
        }
        
        // 获取店铺详情并排序
        List<TopShopsVO.ShopSalesVO> shopSalesList = new ArrayList<>();
        
        for (Map.Entry<Integer, Integer> entry : shopOrderCountMap.entrySet()) {
            Integer shopId = entry.getKey();
            Integer orderCount = entry.getValue();
            Integer salesAmount = shopSalesAmountMap.get(shopId);
            
            Shop shop = shopMapper.selectById(shopId);
            if (shop != null) {
                TopShopsVO.ShopSalesVO shopSales = new TopShopsVO.ShopSalesVO(
                        shopId,
                        shop.getShopName(),
                        shop.getLogo(),
                        orderCount,
                        salesAmount
                );
                shopSalesList.add(shopSales);
            }
        }
        
        // 按销售额排序并限制数量
        shopSalesList.sort((a, b) -> b.getSalesAmount().compareTo(a.getSalesAmount()));
        if (shopSalesList.size() > limit) {
            shopSalesList = shopSalesList.subList(0, limit);
        }
        
        return new TopShopsVO(shopSalesList);
    }

    /**
     * 获取商品分类销售分布
     */
    @Override
    public CategoryDistributionVO getCategoryDistribution() {
        // 查询已完成订单的订单项
        LambdaQueryWrapper<Order> orderQueryWrapper = new LambdaQueryWrapper<>();
        orderQueryWrapper.eq(Order::getStatus, 3); // 已完成状态
        List<Order> completedOrders = orderMapper.selectList(orderQueryWrapper);
        
        if (completedOrders.isEmpty()) {
            return new CategoryDistributionVO(
                    Collections.emptyList(),
                    Collections.emptyList(),
                    Collections.emptyList()
            );
        }
        
        List<Integer> orderIds = completedOrders.stream()
                .map(Order::getOrderId)
                .collect(Collectors.toList());
        
        // 查询这些订单的订单项
        LambdaQueryWrapper<OrderItem> itemQueryWrapper = new LambdaQueryWrapper<>();
        itemQueryWrapper.in(OrderItem::getOrderId, orderIds);
        List<OrderItem> orderItems = orderItemMapper.selectList(itemQueryWrapper);
        
        // 获取商品ID列表
        List<Integer> productIds = orderItems.stream()
                .map(OrderItem::getProductId)
                .collect(Collectors.toList());
        
        // 查询商品信息
        LambdaQueryWrapper<Product> productQueryWrapper = new LambdaQueryWrapper<>();
        productQueryWrapper.in(Product::getProductId, productIds);
        List<Product> products = productMapper.selectList(productQueryWrapper);
        
        // 构建商品ID到分类ID的映射
        Map<Integer, Integer> productToCategoryMap = products.stream()
                .collect(Collectors.toMap(Product::getProductId, Product::getCategoryId));
        
        // 按分类统计销售额
        Map<Integer, Integer> categorySalesMap = new HashMap<>();
        
        for (OrderItem item : orderItems) {
            Integer productId = item.getProductId();
            Integer categoryId = productToCategoryMap.get(productId);
            Integer subtotal = item.getSubtotal();
            
            if (categoryId != null) {
                categorySalesMap.put(categoryId, categorySalesMap.getOrDefault(categoryId, 0) + subtotal);
            }
        }
        
        // 计算总销售额
        int totalSales = categorySalesMap.values().stream().mapToInt(Integer::intValue).sum();
        
        // 获取分类名称并计算占比
        List<String> categoryNames = new ArrayList<>();
        List<Integer> salesAmounts = new ArrayList<>();
        List<Double> percentages = new ArrayList<>();
        
        for (Map.Entry<Integer, Integer> entry : categorySalesMap.entrySet()) {
            Integer categoryId = entry.getKey();
            Integer salesAmount = entry.getValue();
            
            // 查询分类名称
            String categoryName = categoryMapper.selectCategoryNameById(categoryId);
            if (categoryName == null) {
                categoryName = "未知分类";
            }
            
            categoryNames.add(categoryName);
            salesAmounts.add(salesAmount);
            
            // 计算占比
            double percentage = totalSales > 0 ? (double) salesAmount / totalSales * 100 : 0;
            percentages.add(Math.round(percentage * 100) / 100.0); // 保留两位小数
        }
        
        return new CategoryDistributionVO(categoryNames, salesAmounts, percentages);
    }

    /**
     * 获取指定日期范围内的总销售额
     */
    private Integer getTotalSalesForDateRange(LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getStatus, 3) // 已完成状态
                .between(Order::getFinishTime, startTime, endTime);
        
        List<Order> orders = orderMapper.selectList(queryWrapper);
        return orders.stream()
                .mapToInt(Order::getTotalAmount)
                .sum();
    }

    /**
     * 获取指定日期范围内的订单数量
     */
    private Integer getOrderCountForDateRange(LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getStatus, 3) // 已完成状态
                .between(Order::getFinishTime, startTime, endTime);
        
        return orderMapper.selectCount(queryWrapper).intValue();
    }

    /**
     * 计算环比增长率
     */
    private Double calculateGrowthRate(Integer current, Integer previous) {
        if (previous == null || previous == 0) {
            return current > 0 ? 100.0 : 0.0;
        }
        return Math.round((double) (current - previous) / previous * 10000) / 100.0;
    }
}